﻿/******************************************************************************************************
Copyright (c) 2014 Steven Giacomelli (stevegiacomelli@gmail.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************************************/

using SharpGeo.Indexing;
using System;
using System.Collections.Generic;

namespace SharpGeo
{
    /// <summary>
    /// A polyshape map layer (polygons/multipoints/polylines)
    /// </summary>
    public class PolyShapeMapLayer :
        VectorMapLayer,
        IEnumerable<PolyShape>
    {
        #region Constructor

        /// <summary>
        /// Constructs a new PolyShapeLayer
        /// </summary>
        /// <param name="layerID">The uniqueID</param>
        /// <param name="layerName">The display name</param>
        /// <param name="shapes">The shapes to add</param>
        public PolyShapeMapLayer(Guid layerID, string layerName, List<PolyShape> shapes)
            : base(layerID, layerName)
        {
            if (shapes == null)
                throw new ArgumentNullException("shapes", Properties.Resources.PolyShapeMapLayerShapeNullException);

            _shapes = shapes;

            _shapes.Sort((a, b) =>
            {
                int a1 = a.Envelope.Area;
                int a2 = b.Envelope.Area;

                if (a1 < a2)
                    return -1;
                else if (a1 > a2)
                    return 1;
                return 0;
            });

            _polyShapes = new ReadOnlyRTree<PolyShape>(shapes);

            _layerColor = StandardColors.LimeGreen;

            LayerOutlineColor = StandardColors.Black;
            LayerOutlineWidth = 0.5;
        }

        #endregion Constructor

        #region Fields

        private Color _layerColor;
        private double _layerOutlineWidth;
        private Color _layerOutlineColor;
        private List<PolyShape> _shapes = null;
        private ReadOnlyRTree<PolyShape> _polyShapes = null;

        #endregion Fields

        #region Properties

        /// <summary>
        /// Gets/sets the fill color of this layer
        /// </summary>
        public Color LayerColor
        {
            get
            {
                return _layerColor;
            }
            set
            {
                _layerColor = value;
                OnChanged();
            }
        }

        /// <summary>
        /// Gets/sets the width of the outline of this layer
        /// </summary>
        public double LayerOutlineWidth
        {
            get
            {
                return _layerOutlineWidth;
            }
            set
            {
                _layerOutlineWidth = value;
                OnChanged();
            }
        }

        /// <summary>
        /// Gets/sets color of the outline of the layer
        /// </summary>
        public Color LayerOutlineColor
        {
            get
            {
                return _layerOutlineColor;
            }
            set
            {
                _layerOutlineColor = value;
                OnChanged();
            }
        }

        /// <summary>
        /// Gets the envelope of this layer
        /// </summary>
        public override Envelope Envelope
        {
            get { return _polyShapes.Envelope; }
            protected set { }
        }

        /// <summary>
        /// Returns the polyshape stored at the specified index
        /// </summary>
        /// <param name="index">The index to retrieve the polyshape at</param>
        /// <returns>The retrieved polyshape</returns>
        public PolyShape this[int index] { get { return _shapes[index]; } }

        /// <summary>
        /// Gets the number of polyshapes associated with this layer
        /// </summary>
        public int Count { get { return _shapes.Count; } }

        /// <summary>
        /// Gets an RTree containing the polyshapes
        /// </summary>
        public ReadOnlyRTree<PolyShape> PolyShapes
        {
            get { return _polyShapes; }
        }

        #endregion Properties

        #region IEnumerable

        IEnumerator<PolyShape> IEnumerable<PolyShape>.GetEnumerator()
        {
            return this._shapes.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this._shapes.GetEnumerator();
        }

        #endregion IEnumerable
    }
}